#ifndef __fredyn_Panel_h__
#define __fredyn_Panel_h__

#include <mml/Matrix.h>
#include <mml/Plane.h>

#define MAX_VERTICES 8 // 6

namespace xxship
{
    class Panel
    {
        int m_nVertices;                         ///< number of vertices
        mml::Vector3d m_vertices[MAX_VERTICES];  ///< actual vertices
        mml::Vector3d m_centroid;                ///< centroid
        mml::Vector3d m_surfaceVector;           ///< normal * area
        mml::Vector3d m_center;                  ///< average vertex position
        double m_dArea;
        double m_dProjectedArea;
        double m_dMinX;
        double m_dMaxX;
        double m_dMinY;
        double m_dMaxY;
        double m_dMinZ;
        double m_dMaxZ;

    public:

        /** Default constructor. */
        Panel();

        /** Copy constructor. */
        Panel(Panel const& other);

        /** Destructor. */
        ~Panel();

        /** Copy assignment operator. */
        Panel const& operator=(Panel const& other);

        /** Clear the panel. */
        void clear();

        /** Set panel type. */
        void setType(unsigned type);

        /** Number of vertices. */
        int getNumberOfVertices() const;

        /** Centroid. */
        mml::Vector3d const& getCentroid() const;

        /** Normal vector. */
        mml::Vector3d const& getSurfaceVector() const;

        /** Average vertex position. */
        mml::Vector3d getCenter() const;

        /** Area. */
        double getArea() const;

        /** Projected Area. */
        double getProjectedArea() const;

        /** Get vertex. */
        mml::Vector3d const& getVertex(int i) const;

        /** Add vertex. */
        void addVertex(mml::Vector3d const& v);

        /** Compute centroid, normal and area from current vertices. */
        void compute();

        /** Flatten and compute the polygon. */
        void flatten();

        /** Reduced panel (part above plane). */
        Panel createReducedPanel(mml::Planed const& plane) const;

        /** Reduced panel (potatocutter in XY-plane). */
        Panel createReducedPanel(const mml::Planed* pPlanes[]) const;

        /** Rotate panel. */
        void rotate(mml::Matrix3d const& R);

        /** Translate panel. */
        void translate(mml::Vector3d const& translation);

        /** Minimum x-coordinate. */
        double getMinX() const;

        /** Maximum x-coordinate. */
        double getMaxX() const;

        /** Minimum y-coordinate. */
        double getMinY() const;

        /** Maximum y-coordinate. */
        double getMaxY() const;

        /** Minimum z-coordinate. */
        double getMinZ() const;

        /** Maximum z-coordinate. */
        double getMaxZ() const;

        /** Bounding box in XY-plane */
        void getBoundingBox(double* pMinX, double* pMinY, double* pMaxX, double* pMaxY) const;

        /** Project in Z plane */
        Panel createProjectedPanel() const;

    private:

        int find(mml::Vector3d const& v);

        void computeExtremities();
    };
}

#endif
